package com.pince.pushStreaming.pusher

import android.content.Context
import android.hardware.Camera
import android.util.AttributeSet
import android.view.Gravity
import android.view.ViewGroup
import com.pince.pushStreaming.ui.CameraPreviewFrameView
import com.qiniu.android.dns.DnsManager
import com.qiniu.android.dns.IResolver
import com.qiniu.android.dns.http.DnspodFree
import com.qiniu.android.dns.local.AndroidDnsServer
import com.qiniu.pili.droid.streaming.AVCodecType
import com.qiniu.pili.droid.streaming.CameraStreamingSetting
import com.qiniu.pili.droid.streaming.MediaStreamingManager
import com.qiniu.pili.droid.streaming.StreamingProfile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.IOException
import java.net.InetAddress


open class PLStreamController : PLStreamListener {

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    lateinit var mProfile: StreamingProfile
    lateinit var mCameraPreviewSurfaceView: CameraPreviewFrameView
    lateinit var mMediaStreamingManager: MediaStreamingManager


    //初始化方法
    init {
        //创建一个空的界面
    }

    fun setPushPath(url: String): MediaStreamingManager {
        mProfile = StreamingProfile()
        //encoding setting
        mProfile.setVideoQuality(StreamingProfile.VIDEO_QUALITY_MEDIUM2)
                .setAudioQuality(StreamingProfile.AUDIO_QUALITY_MEDIUM2)
                .setEncodingOrientation(StreamingProfile.ENCODING_ORIENTATION.PORT)
                .setEncodingSizeLevel(StreamingProfile.VIDEO_ENCODING_HEIGHT_480)
                .setEncoderRCMode(StreamingProfile.EncoderRCModes.QUALITY_PRIORITY)
                .setBitrateAdjustMode(StreamingProfile.BitrateAdjustMode.Auto)
                .setYuvFilterMode(StreamingProfile.YuvFilterMode.Linear)
                .setPublishUrl(url)


        mProfile.setDnsManager(getMyDnsManager())
                .setStreamStatusConfig(StreamingProfile.StreamStatusConfig(3))
                .setSendingBufferProfile(StreamingProfile.SendingBufferProfile(0.2f, 0.8f, 3.0f, 20 * 1000))
        //相机设置
        val camerasetting = CameraStreamingSetting()
        camerasetting.setCameraId(Camera.CameraInfo.CAMERA_FACING_FRONT)
                .setContinuousFocusModeEnabled(true)
                .setCameraPrvSizeLevel(CameraStreamingSetting.PREVIEW_SIZE_LEVEL.MEDIUM)
                .setCameraPrvSizeRatio(CameraStreamingSetting.PREVIEW_SIZE_RATIO.RATIO_16_9)

        //streaming engine init and setListener
        mCameraPreviewSurfaceView = CameraPreviewFrameView(context)
        this.addView(mCameraPreviewSurfaceView, params)

        if (isDebug) {
            this.addView(logTextView)
        }
        mMediaStreamingManager = MediaStreamingManager(context, mCameraPreviewSurfaceView, AVCodecType.SW_VIDEO_WITH_SW_AUDIO_CODEC) // soft codec
        mMediaStreamingManager.setStreamingSessionListener(this)
        mMediaStreamingManager.setStreamStatusCallback(this)
        mMediaStreamingManager.setAudioSourceCallback(this)
        mMediaStreamingManager.setStreamingStateListener(this)

        mMediaStreamingManager.prepare(camerasetting, mProfile)
        return mMediaStreamingManager
    }

    /**
     * If you want to use a custom DNS server, config it
     * Not required.
     */
    private fun getMyDnsManager(): DnsManager? {
        var r0: IResolver? = null
        val r1: IResolver = DnspodFree()
        val r2: IResolver = AndroidDnsServer.defaultResolver()
        try {
            r0 = com.qiniu.android.dns.local.Resolver(InetAddress.getByName("119.29.29.29"))
        } catch (ex: IOException) {
            ex.printStackTrace()
        }
        return DnsManager(com.qiniu.android.dns.NetworkInfo.normal, arrayOf<IResolver?>(r0, r1, r2))
    }

    fun startStream() {
        GlobalScope.launch(Dispatchers.IO) {
            if (mMediaStreamingManager != null) {
                mMediaStreamingManager.startStreaming()
            }
        }
    }

    protected open fun onResume() {
        if (mMediaStreamingManager != null) {
            mMediaStreamingManager.resume()
        }
    }

    protected open fun onPause() {
        // You must invoke pause here.
        if (mMediaStreamingManager != null) {
            mMediaStreamingManager.pause()
        }
    }

    protected open fun stopStream() {
        if (mMediaStreamingManager != null) {
            mMediaStreamingManager.stopStreaming()
        }
    }

    protected open fun onDestroy() {
        if (mMediaStreamingManager != null) {
            mMediaStreamingManager.destroy()
        }
    }

    //设置流的编码格式，硬件编码失败的时候可以使用软编
    override fun setStreamEncodingType() {
        mMediaStreamingManager.updateEncodingType(AVCodecType.SW_VIDEO_CODEC);
        mMediaStreamingManager.startStreaming();
    }

    //开始推流
    override fun startStreaming(): Boolean {
        startStream()
        return true
    }
}